package com.example.up;

import java.nio.ByteBuffer;
import java.util.Timer;
import java.util.TimerTask;

import com.example.mcu_up.serial.Command_Type;
import com.example.mcu_up.serial.Mcu_Pack;
import com.example.mcu_up.serial.Mcu_Serial;
import com.example.mcu_up.util.MCU_Reader;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;

public class Boot extends Activity {
	private static String name = "";
	private Timer time = new Timer();
	private byte[][] code;
	private Mcu_Serial serial = null;
	private Button starts = null;
	private String title = null;
	private ProgressBar progressBar;
	private int start = 0;

	@SuppressLint("HandlerLeak")
	Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.arg1) {
			case -6:
				Mcu_Pack p = (Mcu_Pack) msg.obj;
				if (p.getLen() == 8) {

					if (title.substring(0, 8).equals(
							getThreeCategory(p.getData())[0])
							&& title.substring(8, 10).equals(
									getThreeCategory(p.getData())[1])) {
						// Toast.makeText(Boot.this,"版本一致可以升级了",
						// Toast.LENGTH_SHORT).show();
					}
				}
				if (p.getLen() == 4) {
					int[] len = Mcu_Pack.readTwoTwo(p.getData());
					Log.i("tts", byteToString(p.getData()));
					start = len[0] + 1;
					if (start <= 255) {
						Toast.makeText(Boot.this, "您所升级的行是" + start,
								Toast.LENGTH_SHORT).show();
						programe();
						starts.setEnabled(false);
					}

				}

				// Toast.makeText(Boot.this,byteToString(p.tobytes()),
				// Toast.LENGTH_SHORT).show();
				Log.i("mcu_ok", "收到的数据：" + byteToString(p.tobytes()));

				Log.i("getdata", "收到的数据：" + byteToString(p.tobytes()));

				switch (p.getType()) {
				case (byte) 0x00:

					// Toast.makeText(Boot.this,Boot.this.getString(R.string.s_success),
					// Toast.LENGTH_SHORT).show();
					break;
				case (byte) 0x02:
					Toast.makeText(Boot.this,
							Boot.this.getString(R.string.s_verify),
							Toast.LENGTH_SHORT).show();
					break;
				case (byte) 0x03:
					Toast.makeText(Boot.this,
							Boot.this.getString(R.string.s_length),
							Toast.LENGTH_SHORT).show();
					break;
				case (byte) 0x04:
					Toast.makeText(Boot.this,
							Boot.this.getString(R.string.s_data),
							Toast.LENGTH_SHORT).show();
					break;
				case (byte) 0x05:
					Toast.makeText(Boot.this,
							Boot.this.getString(R.string.s_cmd),
							Toast.LENGTH_SHORT).show();
					break;
				case (byte) 0x06:
					Toast.makeText(Boot.this,
							Boot.this.getString(R.string.s_device),
							Toast.LENGTH_SHORT).show();
					break;
				case (byte) 0x07:
					Toast.makeText(Boot.this,
							Boot.this.getString(R.string.s_version),
							Toast.LENGTH_SHORT).show();
					break;
				case (byte) 0x08:
					Toast.makeText(Boot.this,
							Boot.this.getString(R.string.s_checksum),
							Toast.LENGTH_SHORT).show();
					break;
				case (byte) 0x09:
					Toast.makeText(Boot.this,
							Boot.this.getString(R.string.s_array),
							Toast.LENGTH_SHORT).show();
					break;
				case (byte) 0x0A:
					Toast.makeText(Boot.this,
							Boot.this.getString(R.string.s_row),
							Toast.LENGTH_SHORT).show();
					break;
				case (byte) 0x0C:
					Toast.makeText(Boot.this,
							Boot.this.getString(R.string.s_app),
							Toast.LENGTH_SHORT).show();
					break;
				case (byte) 0x0D:
					Toast.makeText(Boot.this,
							Boot.this.getString(R.string.s_active),
							Toast.LENGTH_SHORT).show();
					break;
				case (byte) 0x0F:
					Toast.makeText(Boot.this,
							Boot.this.getString(R.string.s_unk),
							Toast.LENGTH_SHORT).show();
					break;
				default:
					break;
				}
				break;
			default:
				break;
			}
		};
	};

	private Handler mmHandler = new Handler() {

		public void handleMessage(Message msg) {

			progressBar.setProgress(msg.what);
			// text.setText(String.valueOf(msg.what));
			if (msg.what == code.length + 1) {
				time.cancel();
				Toast.makeText(Boot.this, "刷机完毕", Toast.LENGTH_LONG).show();
				exit();
			}
		};
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.boot);
		String path = this.getIntent().getStringExtra("path");
		// String path = Environment.getExternalStorageDirectory() +
		// "/download/o2fw-04-20150602.cyacd";
		code = MCU_Reader.getSendBytes(path);
		title = MCU_Reader.readFirst(path);
		// Toast.makeText(Boot.this,code.length+"", Toast.LENGTH_SHORT).show();

		serial = Mcu_Serial.getInstance();
		serial.setHandler(handler);
		serial.start();

		progressBar = (ProgressBar) findViewById(R.id.progress);
		progressBar.setMax(code.length);
		startBoot();
		starts = (Button) findViewById(R.id.ok);

		/*
		 * starts.setOnClickListener(new View.OnClickListener() {
		 * 
		 * @Override public void onClick(View arg0) { // TODO Auto-generated
		 * method stub //Toast.makeText(Boot.this,
		 * "点击一次等３秒左右才会有反应,若没有反应等３秒之后再点击，出现“您所升级的行是：xx”表示 开始刷固件",
		 * Toast.LENGTH_SHORT).show();
		 * 
		 * } });
		 */

	}

	// b是八个字节
	public static String[] getThreeCategory(byte[] b) {
		String[] three = new String[3];
		byte[] siliconid = new byte[4];
		byte[] rev = new byte[1];
		byte[] version = new byte[3];

		siliconid[3] = b[0];
		siliconid[2] = b[1];
		siliconid[1] = b[2];
		siliconid[0] = b[3];

		rev[0] = b[4];
		version[0] = b[7];
		version[1] = b[6];
		version[2] = b[5];

		three[0] = byteToString(siliconid).replace(" ", "");
		three[1] = byteToString(rev).replace(" ", "");
		three[2] = byteToString(version).replace(" ", "");

		return three;
	}

	public static String byteToString(byte[] b) {
		StringBuffer buffer = new StringBuffer(b.length);
		for (int i = 0; i < b.length; i++) {
			String strHex = Integer.toHexString(b[i]).toUpperCase();
			if (strHex.length() > 3) {
				buffer.append(strHex.substring(6) + " ");
			} else if (strHex.length() < 2) {
				buffer.append("0" + strHex + " ");

			} else {
				buffer.append(strHex + " ");
			}
		}
		return buffer.toString();

	}

	public void bootolader() {
		Mcu_Pack pack = new Mcu_Pack();
		pack.setType(Command_Type.ENTER_BOOTLOADER);
		Log.i("mcu_ok", "发送的数据" + byteToString(pack.tobytes()));
		serial.send(pack);
	}

	public void getFlashSize() {
		Mcu_Pack pack = new Mcu_Pack();
		pack.setType(Command_Type.GET_FLASH_SIZE);
		ByteBuffer buffer = ByteBuffer.allocate(1);
		buffer.put((byte) 0x00);
		pack.setData(buffer.array());
		Log.i("mcu_ok", "发送的数据" + byteToString(pack.tobytes()));
		serial.send(pack);
	}

	public void startBoot() {
		TimerTask start = new TimerTask() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				bootolader();
			}
		};

		TimerTask flashSize = new TimerTask() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				getFlashSize();
			}
		};

		time.schedule(start, 1000);
		time.schedule(flashSize, 3000);

	}

	public void sendDate1(byte[] line) {
		Mcu_Pack pack = new Mcu_Pack();
		pack.setType(Command_Type.SEND_DATA);
		pack.setData(MCU_Reader.subSend(line, 0, 53));
		Log.i("mcu_ok", "发送的数据" + byteToString(pack.tobytes()));
		serial.send(pack);
	}

	public void sendDate2(byte[] line) {
		Mcu_Pack pack = new Mcu_Pack();
		pack.setType(Command_Type.SEND_DATA);
		pack.setData(MCU_Reader.subSend(line, 53, 106));
		Log.i("mcu_ok", "发送的数据" + byteToString(pack.tobytes()));
		serial.send(pack);
	}

	public void sendPro(byte[] line, int lin) {
		Mcu_Pack pack = new Mcu_Pack();

		pack.setType(Command_Type.PROGRAM_ROW);

		ByteBuffer buffer = ByteBuffer.allocate(3 + 22);
		buffer.put((byte) 0x00);
		buffer.put(Mcu_Pack.intToBytes_L(lin));
		buffer.put(MCU_Reader.subSend(line, 106, 128));
		pack.setData(buffer.array());

		Log.i("mcu_ok", "发送的数据" + byteToString(pack.tobytes()));
		serial.send(pack);
	}

	public void verfiyRow(int lin) {
		Mcu_Pack pack = new Mcu_Pack();
		pack.setType(Command_Type.VERIFY_ROW);
		ByteBuffer buffer = ByteBuffer.allocate(3);
		buffer.put((byte) 0x00);
		buffer.put(Mcu_Pack.intToBytes_L(lin));
		pack.setData(buffer.array());
		Log.i("mcu_ok", "发送的数据" + byteToString(pack.tobytes()));
		serial.send(pack);
	}

	static int i = 0;

	public void programe() {

		time.schedule(new TimerTask() {

			@SuppressWarnings("static-access")
			@Override
			public void run() {

				if (i < code.length) {

					if (i == code.length - 1)

						sendLine(code[i], 255);
					else {
						sendLine(code[i], start++);
						Log.i("myi1111111111", String.valueOf(start));

					}
				}
				i++;
				mmHandler.sendEmptyMessage(i);
			}
		}, 5000, 500);

	}

	public void sendLine(final byte[] line, final int lin) {

		TimerTask task1 = new TimerTask() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				sendDate1(line);
			}
		};

		TimerTask task2 = new TimerTask() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				sendDate2(line);
			}
		};

		TimerTask task3 = new TimerTask() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				sendPro(line, lin);
			}
		};

		TimerTask task4 = new TimerTask() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				verfiyRow(lin);
			}
		};

		time.schedule(task1, 100);
		time.schedule(task2, 200);
		time.schedule(task3, 300);
		time.schedule(task4, 400);

	}

	public void exit() {
		Mcu_Pack pack = new Mcu_Pack();
		pack.setType(Command_Type.EXIT_BOOTLOADER);
		serial.send(pack);
		Log.i("mcu_ok", "发送的数据" + byteToString(pack.tobytes()));
	}

}